package cc.iotkit.manager.task;

import cc.iotkit.data.dao.DeviceHourlyReportRepository;
import cc.iotkit.data.manager.IDeviceHourlyReportData;
import cc.iotkit.data.manager.IDeviceInfoData;
import cc.iotkit.data.model.TbDeviceHourlyReport;
import cc.iotkit.manager.service.IMapService;
import cc.iotkit.model.device.DeviceHourlyReport;
import cc.iotkit.model.device.DeviceInfo;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 高德同步所有设备的行驶里程，每小时同步
 */
@Component
public class SyncDistanceHourly {
    @Autowired
    private IDeviceInfoData deviceInfoData;
    @Autowired
    private IMapService mapService;
    @Autowired
    private IDeviceHourlyReportData deviceHourlyReportData;
    @Autowired
    private DeviceHourlyReportRepository deviceHourlyReportRepository;
    @Autowired
    private StringRedisTemplate redisTemplate;
    private static Logger logger = LoggerFactory.getLogger(SyncDistanceHourly.class);
    private String LastTimeCacheKey="sync:distance_hourly";

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    @XxlJob("SyncDistanceHourly")
    public void run() throws Exception {
        logger.info("xxl-job:running SyncDistanceHourly...");
        //设置当前日期
        //SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        //SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar c = Calendar.getInstance();

        while (true){
            String lastTime= getLastTime();
            Date startTime = Date.from(LocalDateTime.parse(lastTime).atZone(ZoneId.systemDefault()).toInstant());
            c.setTime(startTime);
            c.add(Calendar.HOUR,1);
            Date endTime = c.getTime();

            //是否大于当前时间
            if(endTime.getTime()<new Date().getTime()){

                 try {
                     DeviceInfo deviceInfo=  new DeviceInfo();
                     deviceInfo.setState(null);
                    List<DeviceInfo> list= deviceInfoData.findAllByCondition(deviceInfo);
                    List<DeviceHourlyReport> reports=new ArrayList<>();
                    for(DeviceInfo info : list){
                        Float distance= 0f;
                        distance= mapService.getDistance(startTime.getTime(),endTime.getTime(),info.getAmapTid(),info.getAmapTrid());
                        //从高德获取的里程数需要乘以系数
                        distance=distance*info.getOffsetCoefficientDistance();
                        if(distance!=null&&distance>0f) {
                            DeviceHourlyReport report = new DeviceHourlyReport();
                            report.setReportDate(endTime);
                            report.setHour(String.valueOf(endTime.getHours()));
                            report.setDistance(distance);
                            report.setDeviceId(info.getDeviceId());
                            report.setSquare(distance * (info.getWidth() == null ? 0 : info.getWidth()));
                            reports.add(report);
                        }

                        /*Float distance= 0f;
                        Float square=0f;

                        //洗地机类型：清扫面积= 清洁时长*车型宽度*车子的平均速度*偏移距离系数
                        if(info.getCategory().equals("004")){
                            TbDeviceHourlyReport row = deviceHourlyReportRepository.findFirstByReportDateAndDeviceId(sdf.format(endTime),String.valueOf(endTime.getHours()), info.getDeviceId());
                            if(row!=null){
                                if(row.getWorkingTimes()>0){
                                    distance=row.getWorkingTimes()*info.getAverageSpeed()*info.getOffsetCoefficientDistance();
                                }
                            }
                        }else{
                            //其他类型：清扫面积=里程数*宽度
                            if(distance!=null&&distance>0f) {
                                distance= mapService.getDistance(startTime.getTime(),endTime.getTime(),info.getAmapTid(),info.getAmapTrid());
                                //从高德获取的里程数需要乘以系数
                                distance=distance*info.getOffsetCoefficientDistance();
                            }
                        }

                        square = distance * (info.getWidth() == null ? 0 : info.getWidth());

                        if(square>0f) {
                            DeviceHourlyReport report = new DeviceHourlyReport();
                            report.setReportDate(endTime);
                            report.setHour(String.valueOf(endTime.getHours()));
                            report.setDistance(distance);
                            report.setDeviceId(info.getDeviceId());
                            report.setSquare(square);
                            reports.add(report);
                        }
                        */

                    }

                    deviceHourlyReportData.batchSave(reports);

                }
                catch (Exception e){
                    logger.info("xxl-job-error:"+e.getMessage());
                    XxlJobHelper.log(e);
                    XxlJobHelper.handleFail();
                }

                lastTime=LocalDateTime.ofInstant(endTime.toInstant(), ZoneId.systemDefault()).toString();
                this.setLastTime(lastTime);
            }else{
                break;
            }
        }

        logger.info("xxl-job:running SyncDistanceHourly finished");
    }


    public String getLastTime() {
        Object last = redisTemplate.opsForValue().get(LastTimeCacheKey);
        if(ObjectUtils.isEmpty(last)){
            Calendar c = Calendar.getInstance();
            return LocalDateTime.of(c.get(Calendar.YEAR),c.get(Calendar.MONTH)+1,c.get(Calendar.DAY_OF_MONTH),0,0,0,0).toString();
        }
        return last.toString();
    }

    public void setLastTime(String lastTime) {
        redisTemplate.opsForValue().set(LastTimeCacheKey, lastTime);
    }
}
